<?php
/**
 * Created by bianquan
 * User: ZhuYunlong
 * Email: 920200256@qq.com
 * Date: 2019/3/2
 * Time: 15:40
 */

namespace app\admin\logic\auth;


use app\admin\enum\AuthEnum;
use app\admin\logic\RestLogic;
use app\admin\model\auth\MenuApi;
use app\admin\model\auth\SystemMenu;
use app\lib\exception\RepeatException;
use app\lib\exception\ResourcesException;
use think\annotation\Inject;
use think\db\Query;

class Menu extends RestLogic
{

    /**
     * @Inject()
     * @var SystemMenu
     */
    protected $model;

    /**
     * 获取列表
     * @return \think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getList()
    {
        return $this->model->with(['api', 'children.api'])
            ->where('father_id', 0)
            ->order('sort', 'asc')
            ->select();
    }

    /**
     * 创建
     */
    public function create()
    {
        /** @var SystemMenu $menu */
        $menu = SystemMenu::create([
            'father_id' => $this->request->post('father_id'),
            'title' => $this->request->post('title'),
            'path' => $this->request->post('path'),
            'name' => $this->request->post('name'),
            'component' => $this->request->post('component'),
            'sort' => $this->request->post('sort'),
            'icon' => $this->request->post('icon'),
            'hidden' => $this->request->post('hidden')
        ]);
        $apiList = $this->request->post('api/a');
        if (count($apiList) > 0) {
            $insert = [];
            foreach ($apiList as $api) {
                $insert[] = [
                    'menu_id' => $menu->menu_id,
                    'api_id' => $api
                ];
            }
            if (count($insert) > 0) {
                (new MenuApi())->insertAll($insert);
            }
        }
    }

    /**
     * 更新操作
     * @throws RepeatException
     * @throws ResourcesException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function update()
    {
        /** @var SystemMenu $menu */
        $menu = $this->model->find($this->request->put('menu_id'));
        if (empty($menu)) {
            throw new ResourcesException();
        }
        $fatherID = $this->request->put('father_id');
        if ($fatherID == $menu->menu_id) {
            throw new RepeatException();
        }
        if ($fatherID != 0) {
            /** @var SystemMenu $father */
            $father = SystemMenu::find($fatherID);
            if (empty($father)) {
                throw new ResourcesException();
            }
            if ($father->father_id != 0) {
                throw new ParameterException(['msg' => '暂时不支持超过二级菜单']);
            }
        }
        $menu->title = $this->request->put('title');
        $menu->path = $this->request->put('path');
        $menu->father_id = $this->request->put('father_id');
        $menu->name = $this->request->put('name');
        $menu->component = $this->request->put('component');
        $menu->sort = $this->request->put('sort');
        $menu->icon = $this->request->put('icon');
        $menu->hidden = $this->request->put('hidden');
        $menu->save();
        $menuApiList = MenuApi::where('menu_id', $menu->menu_id)->select();
        $hasApi = [];
        $insert = [];
        $delete = [];
        $apiList = $this->request->put('api/a');
        foreach ($menuApiList as $menuApi) {
            if (!in_array($menuApi['api_id'], $apiList)) {
                $delete[] = $menuApi['menu_api_id'];
            }
            $hasApi[] = $menuApi['api_id'];
        }
        foreach ($apiList as $api) {
            if (!in_array($api, $hasApi)) {
                $insert[] = [
                    'menu_id' => $menu->menu_id,
                    'api_id' => $api
                ];
            }
        }
        if (count($delete) > 0) {
            MenuApi::destroy($delete, true);
        }
        if (count($insert) > 0) {
            (new MenuApi())->saveAll($insert);
        }
    }

    /**
     * 删除菜单
     * @throws \app\lib\exception\DeleteException
     */
    public function delete()
    {
        parent::delete(); // TODO: Change the autogenerated stub
        MenuApi::where('menu_id', '=', $this->request->delete($this->model->getPk()))
            ->delete();
    }


    /**
     * 获取菜单和绑定的api
     * @return \think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getMenusWithApi()
    {
        return $this->model->with([
            'api', 'children' => function (Query $query) {
                return $query->with('api')
                    ->order('sort', 'desc');
            }
        ])
            ->where('father_id', '=', 0)
            ->order('sort', 'desc')
            ->select();
    }


    /**
     * 更新或添加操作的时候，表单赋值
     */
    protected function setForm()
    {
        // TODO: Implement setForm() method.
    }

    /**
     * 获取角色绑定的前端菜单列表
     * @return \think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getRoleMenus()
    {
        $role = Token::instance()->role();
        return $this->model->with(['children' => function ($query) use ($role) {
            $query->when(AuthEnum::SUPER_ROLE !== $role->role_id, function ($query) use ($role) {
                $query->where('menu_id', 'in', $role->menu_ids);
            })
                ->order('sort asc');
        }])
            ->where('father_id', 0)
            ->when(AuthEnum::SUPER_ROLE !== $role->role_id, function ($query) use ($role) {
                $query->where('menu_id', 'in', $role->menu_ids);
            })
            ->order('sort asc')
            ->select();
    }
}